package com.srxz.mobilepharmacy.service;

import com.alibaba.fastjson.JSON;
import com.srxz.mobilepharmacy.entity.UserInfoPK;
import com.srxz.mobilepharmacy.entity.view.VwMrStk;
import com.srxz.mobilepharmacy.entity.view.VwMrStkParam;
import com.srxz.mobilepharmacy.repository.MrPrfnRepository;
import com.srxz.mobilepharmacy.repository.VwMrStkRepository;
import com.srxz.mobilepharmacy.util.LogTool;
import com.srxz.mobilepharmacy.util.SessionTool;
import com.srxz.mobilepharmacy.util.back.BackMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.orm.jpa.EntityManagerProxy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import javax.persistence.EntityManager;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName: MrService
 * @author: wgchao
 * @createTime: 2018/12/28 1:49 PM
 * @Description: 药品库存盘点service
 */
@Service
@Transactional
@Slf4j
public class MrService {


    @Autowired
    private MrPrfnRepository mrPrfnRepository;
    @Autowired
    private VwMrStkRepository vwMrStkRepository;
    @Autowired
    private EntityManager entityManager;

    @Transactional(readOnly = true)
    public BackMessage findStkBroadHeading(String drugName, Integer page, Integer ord, String asc, HttpSession session){
        Integer msn = SessionTool.getHouse(session);
        BigInteger aid = SessionTool.getUser(session).getAid();
        if(page == null)
            page = 0;
        String sortName = null;
        //获取排序字段
        if(ord == null)
            sortName = null;
        else if(ord == 0)
            sortName = "order by gn ";
        else if(ord == 1)
            sortName = "order by squan ";
        else if(ord == 2)
            sortName = "order by mid ";
        else if(ord == 3)
            sortName = "order by midcl ";

        Pageable pageable = null;
        if(!StringUtils.isEmpty(sortName)){
            if(StringUtils.isEmpty(asc)){
                sortName = "";
            }
            else if(asc.equals("asc")){
                sortName += "asc";
            }else{
                sortName += "desc";
            }
        }else
            sortName = "";

        List<VwMrStk> vwMrStk = new ArrayList<>();
        List res = null;
        if(StringUtils.isEmpty(drugName)){
            String hql = String.format("select stk.aid,stk.mid, stk.gn, stk.wn, stk.made, stk.spr, stk.utr, stk.midcl, sum(stk.quan) as squan " +
                    "from VwMrStk stk where stk.aid="+aid+" and stk.mrn = "+msn +
                    " group by stk.aid,stk.mid, stk.gn, stk.wn, stk.made, stk.spr, stk.utr ,stk.midcl "+sortName);
            res = entityManager.createQuery(hql).setFirstResult(page*10).setMaxResults((page+1)*10).getResultList();
        }else{
            StringBuilder sb = new StringBuilder();
            sb.append("select stk.aid,stk.mid, stk.gn, stk.wn, stk.made, stk.spr, stk.utr, stk.mid_cl, sum(stk.quan) as squan ");
            sb.append("from VwMrStk stk where ");
            sb.append(" stk.aid="+aid+" and stk.mrn="+msn);
            sb.append(" and (stk.gn like '%"+drugName+"%' or stk.wn like '%"+drugName+"%')");
            sb.append(" group by stk.aid,stk.mid, stk.gn, stk.wn, stk.made, stk.spr, stk.utr ,stk.midcl "+sortName);

            res = entityManager.createQuery(sb.toString()).setFirstResult(page*10).setMaxResults((page+1)*10).getResultList();
        }
        for (Object row:res) {
            Object[] objs = (Object[]) row;
            vwMrStk.add(new VwMrStk(objs));
        }

        return BackMessage.success().putData("stk", vwMrStk);
    }

    @Transactional(readOnly = true)
    public BackMessage findStkOfPh(BigInteger aid, Integer mid, Boolean zero, HttpSession session){
        Integer msn = SessionTool.getHouse(session);
        List<VwMrStk> vwMrStks = null;
        if(!zero){//隐藏零库存
            vwMrStks = vwMrStkRepository.findStkZero(aid, mid, msn);
        }else{
            vwMrStks = vwMrStkRepository.findStk(aid, mid, msn);
        }
        return BackMessage.success().putData("stkdetail", vwMrStks);
    }

    /**
     * 库存盘点操作（盘盈？盘亏？）
     * 做相应的日志记录 时间-操作人-盘点操作-盘点数据-结果
     * @param param
     * @param session
     * @return
     */
    public BackMessage saveSTK(List<VwMrStkParam> param, HttpSession session){
        UserInfoPK uid = SessionTool.getUser(session);
        Integer msn = SessionTool.getHouse(session);
        long bs = System.currentTimeMillis();
        //日志记录
        LogTool.pdLog(2, bs, uid, param, msn.toString());

        for(VwMrStkParam vwMrStkParam : param){

            //TODO 数据检查
            if(vwMrStkParam.getVwMrStks()==null || vwMrStkParam.getVwMrStks().isEmpty()){
                continue;
            }
            Double realsum = 0.00;
            Double syssum = 0.00;
            Double mny = 0.00;
            List<VwMrStk> vwMrStks = new ArrayList<>();
            for(VwMrStk vwMrStk : vwMrStkParam.getVwMrStks()){
                if(vwMrStk.getQuan().compareTo(vwMrStk.getRealquan()) != 0){
                    vwMrStks.add(vwMrStk);
                    realsum += vwMrStk.getRealquan();
                    syssum += vwMrStk.getQuan();
                    if(vwMrStkParam.getTyp() == 1)
                        mny += vwMrStk.getPri()*(vwMrStk.getRealquan()-vwMrStk.getQuan());
                    else
                        mny += vwMrStk.getPri()*(vwMrStk.getQuan()-vwMrStk.getRealquan());
                }
            }
            int typ = vwMrStkParam.getTyp();
            Double sub = 0.00;
            if(typ == 1){
           //     System.out.println("盘盈");
                sub = new BigDecimal(realsum).subtract(new BigDecimal(syssum)).doubleValue();
            }else if(typ == 2){
                typ = 2;//亏
           //     System.out.println("盘亏");
                sub = new BigDecimal(syssum).subtract(new BigDecimal(realsum)).doubleValue();
            }else{
                throw new RuntimeException("盘点类型错误？请确定是盘盈还是盘亏");
            }
            vwMrStkParam.setVwMrStks(vwMrStks);

      //      int i = 10/0;

            //获取最新的单据号
            BigInteger prf = findPrfnNew(session, typ);
            if(prf == null){
                return BackMessage.error("库存盘点失败，没有获取到最新的单据号");
            }
            //保存单据
            BigInteger mspid = prfnSave(vwMrStkParam, session, typ, mny);
            if(mspid == null){
                throw new RuntimeException("保存单据失败");
            }
            //循环保存明细
            stkexpSave(vwMrStkParam, session, typ, mspid);

            //确认执行入库操作
            stkexpe(vwMrStkParam, session, mspid, typ);
        }
//        try{
//            //成功后 重新查询药品的明细
//            List<VwMrStk> vwMrStks = vwMrStkRepository.findStk(param.get(0).getAid(), param.get(0).getMid(),
//                    SessionTool.getHouse(session));
//            return BackMessage.success().putData("stkdetail", vwMrStks);
//        }catch (Exception e){
//            e.printStackTrace();
//        }

        LogTool.resLog(2, bs, "盘点成功");
        return BackMessage.success();
    }


    /**
     * 获取最新单据号
     * @return
     */
    public BigInteger findPrfnNew(HttpSession session, int typ){
        //获取当前用户机构编号、药房编号
        UserInfoPK uid = SessionTool.getUser(session);
        Integer msn = SessionTool.getHouse(session);
        BigInteger prf = mrPrfnRepository.mrprfnnew(uid.getAid(), msn, typ);
        return prf;
    }

    /**
     * 保存单据
     * @param vwMrStkParam
     * @param session
     * @param typ 1:盘盈 2；盘亏
     */
    public BigInteger prfnSave(VwMrStkParam vwMrStkParam, HttpSession session, int typ, Double tmy){

        //获取当前用户机构编号、药房编号
        UserInfoPK uid = SessionTool.getUser(session);
        Integer msn = SessionTool.getHouse(session);
        String note = null;
        if(typ == 1)
            note = "盘盈药品一宗";
        else
            note = "盘亏药品一宗";

        //TODO oppo 出库单位,tmy
        BigInteger prf = mrPrfnRepository.mrprfnsave(uid.getAid(), msn, typ, null, 0, note, tmy, 0,
                uid.getName(), "",BigInteger.ZERO, 0.00, BigInteger.ZERO, 0);
        return prf;
    }

    /**
     * 循环保存明细
     * @param vwMrStkParam
     * @param session
     * @param typ
     * @param pn
     */
    public void stkexpSave(VwMrStkParam vwMrStkParam, HttpSession session, int typ, BigInteger pn){

        //获取当前用户机构编号、药房编号
        UserInfoPK uid = SessionTool.getUser(session);
        Integer msn = SessionTool.getHouse(session);
        String note = null;
        if(typ == 1)
            note = "盘盈药品一宗";
        else
            note = "盘亏药品一宗";

        //遍历明细
        for(VwMrStk item : vwMrStkParam.getVwMrStks()){
            Double sub = 0.00;
            if(typ == 1){
                sub = new BigDecimal(item.getRealquan()).subtract(new BigDecimal(item.getQuan())).doubleValue();
                mrPrfnRepository.mrstkimpsave(uid.getAid(), msn, pn.intValue(), item.getMid(), item.getBn(),
                        BigDecimal.valueOf(sub), BigDecimal.valueOf(item.getPri()), BigDecimal.valueOf(item.getPrr()), item.getVdate(),
                        "");
            }else{
                sub = new BigDecimal(item.getQuan()).subtract(new BigDecimal(item.getRealquan())).doubleValue();
                //TODO 盘亏 attr, pro
                mrPrfnRepository.mrstkexpsave(uid.getAid(), msn, typ, pn.intValue(), item.getMid(), 1, item.getBn(),
                        item.getVdate(), BigDecimal.valueOf(sub), BigDecimal.valueOf(item.getPri()), BigDecimal.valueOf(item.getPrr()),
                        BigDecimal.valueOf(item.getPrr()), "");
            }
        }

    }

    /**
     * 确认执行出库操作
     * @param vwMrStkParam
     * @param session
     * @param pn
     */
    public void stkexpe(VwMrStkParam vwMrStkParam, HttpSession session, BigInteger pn, int typ){

        //获取当前用户机构编号、药房编号
        UserInfoPK uid = SessionTool.getUser(session);
        if(typ == 1)
            mrPrfnRepository.mrstkimpe(vwMrStkParam.getAid(), pn.intValue(), uid.getName(), "");
        else
            mrPrfnRepository.mrstkexpe(vwMrStkParam.getAid(), pn.intValue(), uid.getName(), "");

    }


}
